/**
 * @author Jason Pratt
 */

package edu.cmu.cs.stage3.alice.authoringtool.viewcontroller;

import java.awt.Component;

import edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool;
import edu.cmu.cs.stage3.alice.authoringtool.AuthoringToolResources;
import edu.cmu.cs.stage3.alice.authoringtool.datatransfer.TransferableFactory;
import edu.cmu.cs.stage3.util.StringObjectPair;

public class ElementPrototypeDnDPanel extends edu.cmu.cs.stage3.alice.authoringtool.util.DnDGroupingPanel implements edu.cmu.cs.stage3.alice.authoringtool.util.GUIElement, edu.cmu.cs.stage3.alice.authoringtool.util.Releasable {

 protected static TilePool tilePool = new TilePool();

 protected edu.cmu.cs.stage3.alice.authoringtool.util.ElementPrototype elementPrototype;
 protected javax.swing.JPanel subPanel = new edu.cmu.cs.stage3.alice.authoringtool.util.GroupingPanel(); // create a JPanel
 protected String elementName;
 protected java.awt.GridBagConstraints constraints = new java.awt.GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 0, 0, 0 ), 0, 0 );

 public ElementPrototypeDnDPanel () {
  subPanel.setLayout( new java.awt.GridBagLayout() );
  subPanel.setOpaque( false );
  subPanel.setBorder( null );
  this.add( subPanel, java.awt.BorderLayout.CENTER );
  this.addDragSourceComponent( subPanel ); // hack for stencils
 }

 public void set( edu.cmu.cs.stage3.alice.authoringtool.util.ElementPrototype elementPrototype ) {
  this.elementPrototype = elementPrototype;
  this.setTransferable( TransferableFactory.createTransferable( elementPrototype ) );

  if (edu.cmu.cs.stage3.alice.core.response.CallToUserDefinedResponse.class.isAssignableFrom( elementPrototype.getElementClass() ) ) {
   this.setBackground( AuthoringToolResources.getColor( "userDefinedResponse" ) );
  } else if (edu.cmu.cs.stage3.alice.core.Response.class.isAssignableFrom( elementPrototype.getElementClass() ) ) {
   this.setBackground( AuthoringToolResources.getColor( "response" ) );
  } else if (edu.cmu.cs.stage3.alice.core.question.userdefined.CallToUserDefinedQuestion.class.isAssignableFrom( elementPrototype.getElementClass() ) ) {
   this.setBackground( AuthoringToolResources.getColor( "userDefinedQuestion" ) );
  } else if (edu.cmu.cs.stage3.alice.core.Question.class.isAssignableFrom( elementPrototype.getElementClass() ) ) {
   this.setBackground( AuthoringToolResources.getColor( "question" ) );
  } else if (edu.cmu.cs.stage3.alice.core.question.userdefined.Component.class.isAssignableFrom( elementPrototype.getElementClass() ) ) {
   this.setBackground( AuthoringToolResources.getColor( "userDefinedQuestionComponent" ) );
  } else {
   this.setBackground( AuthoringToolResources.getColor( "elementPrototypeDnDPanel" ) );
  }

  elementName = AuthoringToolResources.getReprForValue( elementPrototype.getElementClass() );

  refreshGUI();
 }

 public void goToSleep() {}
 public void wakeUp() {}

 public void clean() {
  this.elementPrototype = null;
  this.setTransferable( null );
  refreshGUI();
 }

 public void die() {
  clean();
  subPanel.removeAll();
  removeAll();
 }

 //Rem @Override
 public void release () {
  edu.cmu.cs.stage3.alice.authoringtool.util.GUIFactory.releaseGUI( this );
 }

 public void refreshGUI () {
  java.awt.Component[] components = subPanel.getComponents();
  //LOB for (Component component2 : components)
  int t_tam = components!=null ? components.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   if (components[i_i] instanceof Tile ) { //L if (component2 instanceof Tile )
    this.removeDragSourceComponent( components[i_i] ); //L ...( component2 );
    tilePool.releaseTile( ((Tile)components[i_i]).getText(), (Tile)components[i_i] ); //L tilePool.releaseTile( ((Tile)component2).getText(), (Tile)component2 );
   }
  } // for (int i_i=0; i_i<t_tam; i_i++)

  subPanel.removeAll();

  if (elementPrototype != null ) {
   StringObjectPair[] propertyValues = elementPrototype.getKnownPropertyValues();
   java.util.Vector keys = new java.util.Vector();
   java.util.HashMap propertyMap = new java.util.HashMap();
   //LOB for (StringObjectPair propertyValue : propertyValues)
   t_tam = propertyValues!=null ? propertyValues.length : 0;
   for (int i_i=0; i_i<t_tam; i_i++) {
    keys.add( propertyValues[i_i].getString() ); //L keys.add( propertyValue.getString() );
    propertyMap.put( propertyValues[i_i].getString(), propertyValues[i_i].getObject() ); //L propertyMap.put( propertyValue.getString(), propertyValue.getObject() );
   }

   constraints.gridx = 0;
   String format = AuthoringToolResources.getFormat( elementPrototype.getElementClass() );
   edu.cmu.cs.stage3.alice.authoringtool.util.FormatTokenizer tokenizer = new edu.cmu.cs.stage3.alice.authoringtool.util.FormatTokenizer( format );
   while( tokenizer.hasMoreTokens() ) {
    String token = tokenizer.nextToken();
    if (token.startsWith( "<<<" ) && token.endsWith( ">>>" ) ) {
     String propertyName = token.substring( token.lastIndexOf( "<" ) + 1, token.indexOf( ">" ) );
     if (keys.contains( propertyName ) ) {
      addTile( AuthoringToolResources.getReprForValue( propertyMap.get( propertyName ), false ), true );
      constraints.gridx++;
      keys.remove( propertyName );
     } else {
      AuthoringTool.getInstance().showErrorDialog( "no value available for " + token, null );
      addTile( token, true );
      constraints.gridx++;
     }
    } else if (token.startsWith( "<<" ) && token.endsWith( ">>" ) ) {
     // skip this one
    } else if (token.startsWith( "<" ) && token.endsWith( ">" ) ) {
     token = token.substring( token.lastIndexOf( "<" ) + 1, token.indexOf( ">" ) );
     addTile( token, true );
     constraints.gridx++;
    } else {
     while( token.indexOf( "&lt;" ) > -1 ) {
      token = new StringBuffer( token ).replace( token.indexOf( "&lt;" ), token.indexOf( "&lt;" ) + 4, "<" ).toString();
     }
     addTile( token, false );
     constraints.gridx++;
    }
   }
  }

  revalidate();
  repaint();
 }

 public void addTile( String text, boolean opaque ) {
  Tile tile = tilePool.getTile( text );
  tile.setOpaque( opaque );
  tile.setBorderEnabled( opaque );
  subPanel.add( tile, constraints );
  this.addDragSourceComponent( tile ); // hack for stencils
 }

 public static class Tile extends edu.cmu.cs.stage3.alice.authoringtool.util.GroupingPanel {
  protected String text;


  // To any JPanel with values, including commands "Print" and "Wait" (these two are in wrong place??)
  // They are defined in: edu.cmu.cs.stage3.alice.core.World -> ReferenceFrame -> Sandbox: public final ElementArrayProperty responses, behaviors, variables, questions
  public Tile( String text ) { // create a JPanel
   this.text = text;
   setLayout( new java.awt.BorderLayout() );
   setBackground( AuthoringToolResources.getColor( "prototypeParameter" ) );
   // if (text!=null && (text.equals("Imprima ") || text.equals("Espere "))) {
   // System.out.println("ElementPrototypeDnDPanel.java; Tile("+text+")");
   // }
   javax.swing.JLabel tileLabel = new javax.swing.JLabel( text );
   tileLabel.setBorder( javax.swing.BorderFactory.createEmptyBorder( 0, 2, 0, 2 ) );
   add( tileLabel, java.awt.BorderLayout.CENTER );
  }

  public String getText() {
   return text;
  }

  public void setBorderEnabled( boolean enabled ) {
   if (enabled ) {
    setBorder( border );
   } else {
    setBorder( null );
   }
  }

  //Rem @Override
  public void release() {
   // don't remove anything
  }
 }

 static class TilePool {
  protected java.util.HashMap tileListMap = new java.util.HashMap();

  public Tile getTile( String text ) {
   java.util.LinkedList tileList = (java.util.LinkedList)tileListMap.get( text );
   if ((tileList != null) && (! tileList.isEmpty()) ) {
    return (Tile)tileList.removeFirst();
   } else {
    Tile tilePanel = new Tile( text );
    return tilePanel;
   }
  }

  public void releaseTile( String text, Tile tile ) {
   java.util.LinkedList tileList = (java.util.LinkedList)tileListMap.get( text );
   if (tileList == null ) {
    tileList = new java.util.LinkedList();
    tileListMap.put( text, tileList );
   }
   tileList.addFirst( tile );
  }
 }

}
